/*!
 *2018.07.04 wxd
 */
;
(function(factory) {
	if(typeof define === 'function' && define.amd) {
		define(['jquery', 'vw.dialog', 'vw.common', 'bootstrap', 'bootstrap.treeview', 'select2-cn', 'bDialog', 'bootstrap.validator-cn', 'vw.static'], factory);
	} else {
		if(typeof module === 'object' && module.exports) {
			//
		} else {
			factory(window.jQuery);
		}
	}
})(function($, vw_dialog) {
	'use strict';
	var pluginName = "vw_searchtree";
	var defaults = {
		showEdit: false,
		showSearch: true,
		showCheckbox: false,
		$container: null,
		height: 50,
		heightDiff: 45,
		checkStatName: "",
		data: "",
		dataurl: "",
		infourl: "",
		saveurl: "",
		deleteurl: "",
		menu: [],
		defaultMenuID: 1,
		multipleSelect: "",
		selectFirst: true,
		selectNodeID: "",
		selectChildNodeOnly: false,
		breadcrumbID: "",
		tagsClass: "badge",
		tagColor: "#5cb85c",
		levels: 10,
		paraType: 'type',
		paraCatalogID: 'catalogID',
		paraTableInfo: 'tableInfo',
		dataResponseName: 'data',
		infoResponseName: 'data',
		omitCharNum: 12, //设置文字超过多少个字符变成省略号
		emptyIcon: 'glyphicon glyphicon-file',
		extrapara: {},
		onMenuChanged: undefined,
		onTreeSelected: undefined,
		onTreeUnselected: undefined,
		onNodeChecked: undefined,
		onNodeUnchecked: undefined,
		onTreeInitialized: undefined,
		onHomeClick: undefined
	};

	var methods = [
		'GetOptions',
		'GetSearchVal',
		'GetSelected',
		'GetChecked',
		"SelectNode",
		"checkNode",
		'destroy'
	];

	var vw_searchtree = function(element, options) {
		this.$element = $(element);
		this.options = $.extend({}, defaults, options);
		this._defaults = defaults;
		this._name = pluginName + this.$element.attr('id');
		this.version = 'v1.0.0';
		this._init();
	}

	vw_searchtree.prototype = {
		_init: function() {
			var that = this;
			var HTML_EDIT = [
				'<div class="row">',
				'	<div class="col-md-12">',
				'		<div class="pull-right">',
				'			<button id="' + that._name + '-fnNew" class="btn btn-primary"><i class="glyphicon glyphicon-plus"></i></button>',
				'			<button id="' + that._name + '-fnEdit" class="btn btn-primary"><i class="glyphicon glyphicon-pencil"></i></button>',
				'			<button id="' + that._name + '-fnDelete" class="btn btn-primary"><i class="glyphicon glyphicon-trash"></i></button>',
				'		</div>',
				'	</div>',
				'</div>'
			].join("");

			var li = "";
			$.each(that.options.menu, function(k, val) {
				li += '<li menu="menu_' + val.id + '" ';
				if(val.id == that.options.defaultMenuID) {
					li += 'class="active"';
				}
				li += '><a href="#" data-toggle="tab">' + val.text + '</a></li>';
			});
			var HTML_MENU = [
				'<div class="row">',
				'	<div class="col-md-12">',
				'		<ul id="' + that._name + '-menutype" class="nav nav-tabs">',
				li,
				'		</ul>',
				'	</div>',
				'</div>'
			].join("");

			var HTML_SEARCH = ['<div class="row">',
				'	<div class="col-md-12" style="margin: 10px 0;">',
				'		<select id="' + that._name + '-select" style="width: 100%;"></select>',
				'	</div>',
				'</div>',
			].join("");

			that.$element.append([
				that.options.showEdit ? HTML_EDIT : "",
				that.options.showSearch ? HTML_SEARCH : "",
				that.options.menu.length > 0 ? HTML_MENU : "",
				'<div class="row">',
				'	<div class="col-md-12">',
				'		<div id="' + that._name + '-tree" style="white-space: nowrap;overflow-y: auto;"></div>',
				'	</div>',
				'</div>',
			].join(""));

			that.$search = $('#' + that._name + '-select');
			that.$tree = $('#' + that._name + '-tree');

			if(that.options.showEdit) {
				that.$fnNew = $('#' + that._name + '-fnNew');
				that.$fnEdit = $('#' + that._name + '-fnEdit');
				that.$fnDelete = $('#' + that._name + '-fnDelete');

				that.$fnNew.on('click', function() {
					that._fnNew();
				});

				that.$fnEdit.on('click', function() {
					that._fnEdit();
				});

				that.$fnDelete.on('click', function() {
					that._fnDelete();
				});

				that.$fnEdit.prop('disabled', true);
				that.$fnDelete.prop('disabled', true);
			}

			that.$search.select2({
				multiple: that.options.multipleSelect,
				minimumInputLength: 1,
				placeholder: "输入关键字或拼音...",
				language: "zh-CN",
				allowClear: true,
			});

			that.$search.on('select2:unselect', function() {
				that.$tree.treeview('clearSearch');
				that.$tree.treeview('collapseAll', {
					silent: true
				});
				$.each(that._allNodes, function(k, val) {
					that.$tree.treeview('unselectNode', [val, {
						silent: false
					}]);
				});
			});

			that.$search.on('select2:select', function(e) {
				if(e.params) {
					that._scrollToItem(e.params.data.id);
				}
			});

			if(that.options.menu.length > 0) {
				that.$menutype = $('#' + that._name + '-menutype');
				that.$menutype.find('li>a').css('padding', '5px 10px');

				that.options.extrapara.type = that.options.defaultMenuID ? that.options.defaultMenuID : that.options.menu[0].id;

				that.$menutype.find('li').on('click', function() {
					that.options.extrapara.type = $(this).attr('menu').split('_')[1];
					if(!that.options.data) {
						that._ajaxLoadTreeData();
					} else {
						that._LoadTreeData(that.options.data);
					}

					that.$element.trigger("onMenuChanged", that.options.extrapara.type);
					if(that.options.onMenuChanged) {
						that.options.onMenuChanged.call(that, that.options.extrapara.type);
					}
				});
			} else {
				that.options.extrapara.type = that.options.defaultMenuID;
			}

			if(that.options.breadcrumbID) {
				that.$breadcrumb = $('#' + that.options.breadcrumbID);

				that.$breadcrumb.append([
					'<ol class="breadcrumb" style="margin-bottom: 0;">',
					'	<li><a href="#"><span class="fa fa-home"></span></a></li>',
					'</ol>'
				].join(""));

				that.$breadcrumb.on('click', 'a', function() {
					var id = $(this).attr("nodeId");
					if(id) {
						$.each(that._allNodes, function(k, val) {
							if(val.nodeId == id) {
								that.$tree.treeview('selectNode', [val, {
									silent: false
								}]);
								that._curBreadSelectNode = val;
							} else {
								that.$tree.treeview('unselectNode', [val, {
									silent: false
								}]);
							}
						});
					} else {
						that.$element.trigger("onHomeClick");
						if(that.options.onHomeClick) {
							that.options.onHomeClick.call(that);
						}
						that._RefreshBreadcrumb();
						that.$search.val(null).trigger('change');
						$.each(that._allNodes, function(k, val) {
							that.$tree.treeview('unselectNode', [val, {
								silent: false
							}]);
						});
						that.$tree.treeview('collapseAll', {
							silent: true
						});
						that._curBreadSelectNode = null;
					}
				});
			};

			if(!that.options.data) {
				that._ajaxLoadTreeData();
			} else {
				that._LoadTreeData(that.options.data);
			}

			resize();
			$(window).resize(resize);

			function resize() {
				var containerHeight;
				if(that.options.$container) {
					containerHeight = that.options.$container.height();
				} else {
					if(that.options.height) {
						containerHeight = that.options.height;
					} else {
						containerHeight = $(window).height();
					}
				}

				that.height = containerHeight - that.options.heightDiff;

				if(that.options.showEdit) {
					that.height -= 35;
				}
				if(that.options.menu.length) {
					that.height -= 35;
				}
				that.$tree.css({
					"height": that.height + "px",
					"overflow-x": "hidden"
				});
			}
		},

		_scrollToItem: function(id) {
			var that = this;
			//			var searchVal = that.$tree.treeview('search', [text, {
			//				ignoreCase: false, //忽略大小写
			//				exactMatch: false, //精确查询
			//				revealResults: true, //动态标识
			//			}]);
			$.each(that._allNodes, function(k, val) {
				if(id == val.id) {
					that.$tree.treeview('collapseAll', {
						silent: true
					});
					that.$tree.treeview('expandAll', {
						levels: val.level,
						silent: true
					});
					that.$tree.treeview('selectNode', [val, {
						silent: false
					}]);

					//滑动到匹配到的结点并选中
					var $item = that.$tree.find("li:not(.node-hidden)");
					var totalHeight = 0;
					$.each($item, function(i, v) {
						var nodeid = $(v).attr("data-nodeid");
						if(nodeid == val.nodeId) {
							that.$tree.scrollTop(totalHeight);
							return false;
						}
						totalHeight += $(v).outerHeight(true);
					});
					return false;
				}
			});
		},

		_fnNew: function() {
			var that = this;
			if(!that.options.infourl || !that.options.saveurl) {
				return;
			}

			vw_dialog().open({
				type: that.options.extrapara.type,
				catalogID: -1,
				infourl: that.options.infourl,
				saveurl: that.options.saveurl,
				callback: function() {
					that._ajaxLoadTreeData();
				}
			});
		},

		_fnEdit: function() {
			var that = this;
			if(!that.options.infourl || !that.options.saveurl) {
				return;
			}

			vw_dialog().open({
				title: '修改',
				fnButtonName: "保存",
				type: that.options.extrapara.type,
				catalogID: that.$tree.treeview('getSelected')[0].id,
				infourl: that.options.infourl,
				saveurl: that.options.saveurl,
				callback: function() {
					that._ajaxLoadTreeData();
				}
			});
		},

		_fnDelete: function() {
			var that = this;
			if(!that.options.deleteurl) {
				return;
			}

			bDialog.alert('确认删除吗？删除后将无法恢复！', function() {
				var ajaxdata = {};
				ajaxdata[that.options.paraCatalogID] = that.$tree.treeview('getSelected')[0].id;
				ajaxdata[that.options.paraType] = that.options.extrapara.type;

				vw_common.customAjax({
					url: that.options.deleteurl,
					type: "GET",
					dataType: "json",
					data: ajaxdata
				}, function() {
					that._ajaxLoadTreeData();

					$.Notify({
						caption: "成功",
						content: "数据已删除",
						type: "success"
					});
				});
			}, {
				messageType: 'confirm',
				cancel: function() {}
			});
		},

		_ajaxLoadTreeData: function() {
			var that = this;

			vw_common.customAjax({
				url: that.options.dataurl,
				type: "GET",
				dataType: "json",
				data: that.options.extrapara
			}, function(e) {
				that._LoadTreeData(e[that.options.dataResponseName])
			});
		},

		_LoadTreeData: function(data) {
			var that = this;

			$.each(data, function(k, val) {
				val.checkable = that.options.showCheckbox;
				if(val[that.options.checkStatName]) {
					val.state = {};
					val.state.checked = true;
				}
			});

			that.$tree.treeview({
				data: vw_static.listToTree(data, that.options.omitCharNum),
				color: "#337ab7",
				multiSelect: that.options.multipleSelect,
				selectedBackColor: "#337ab7",
				showBorder: false,
				showTags: true,
				tagsClass: that.options.tagsClass,
				levels: that.options.levels,
				expandIcon: 'glyphicon glyphicon-chevron-right',
				emptyIcon: that.options.emptyIcon,
				showCheckbox: that.options.showCheckbox,
				hierarchicalCheck: that.options.showCheckbox,
				onNodeSelected: function(event, node) { 
					if(node.nodes && that.options.selectChildNodeOnly) {
						that.$tree.treeview('unselectNode', [node, {
							silent: false
						}]);

						$.each(that._allNodes, function(k, val) {
							if(val.nodeId == node.nodeId) {
								val.state.selected = false;
							}
						});

						return;
					}

					if(that._curBreadSelectNode) {
						that.$tree.treeview('unselectNode', [that._curBreadSelectNode, {
							silent: false
						}]);
						that._curBreadSelectNode = null;
					}

					if(that.options.showEdit) {
						that.$fnEdit.prop('disabled', false);
						that.$fnDelete.prop('disabled', false);
					}

					that.$element.trigger("onTreeSelected", {
						node: node,
						type: that.options.extrapara.type
					});
					if(that.options.onTreeSelected) {
						that.options.onTreeSelected.call(that, node, that.options.extrapara.type);
					}

					that._RefreshBreadcrumb(node);
				},
				onNodeUnselected: function(event, node) {
					if(node.nodes && that.options.selectChildNodeOnly) {
						return;
					}

					that.$tree.treeview('clearSearch');

					if(that.options.showEdit) {
						that.$fnEdit.prop('disabled', true);
						that.$fnDelete.prop('disabled', true);
					}

					that.$element.trigger("onTreeUnselected", {
						node: node,
						type: that.options.extrapara.type
					});
					if(that.options.onTreeUnselected) {
						that.options.onTreeUnselected.call(that, node, that.options.extrapara.type);
					}
					//that._RefreshBreadcrumb();
				},
				onNodeChecked: function(event, node) {
					that.$element.trigger("onNodeChecked", {
						node: that.$tree.treeview('getChecked'),
						type: that.options.extrapara.type
					});
					if(that.options.onNodeChecked) {
						that.options.onNodeChecked.call(that, that.$tree.treeview('getChecked'), that.options.extrapara.type);
					}
				},
				onNodeUnchecked: function(event, node) {
					that.$element.trigger("onNodeUnchecked", {
						node: node,
						type: that.options.extrapara.type
					});
					if(that.options.onNodeUnchecked) {
						that.options.onNodeUnchecked.call(that, node, that.options.extrapara.type);
					}
				},
				onRendered: function(event, nodes) {
					that.$element.trigger("onTreeInitialized", {
						nodes: nodes,
						type: that.options.extrapara.type
					});
					if(that.options.onTreeInitialized) {
						that.options.onTreeInitialized.call(that, nodes, that.options.extrapara.type);
					}
				}
			});

			that._allNodes = that.$tree.treeview('getNodes');

			//默认选择第一个叶节点
			if(that.options.selectFirst) {
				$.each(that._allNodes, function(k, val) {
					if(!val.isChild) {
						that.$tree.treeview('selectNode', [val, {
							silent: false
						}]);
						return false;
					}
				});
			}

			//默认选择指定节点
			if(that.options.selectNodeID) {
				$.each(that._allNodes, function(k, val) {
					if(that.options.selectNodeID && val.id == that.options.selectNodeID) {
						that.$tree.treeview('selectNode', [val, {
							silent: false
						}]);
						return false;
					}
				});
			}

			that.$tree.find('.list-group-item').css("padding", "8px 15px");

			that.$tree.find('.list-group-item>.badge').css({
				"position": "absolute",
				"right": "5px",
				"background-color": that.options.tagColor
			})

			if(that.$search) {
				that.$search.empty();
				for(var i = 0; i < data.length; i++) {
					that.$search.append('<option value="' + data[i].id + '">' + data[i].text + '</option>');
				};
				that.$search.val(null).trigger('change');
			};
		},

		GetOptions: function() {
			return this.options;
		},

		GetSearchVal: function() {
			return this.$search.select2('data');
		},

		GetSelected: function() {
			var that = this;
			if(!that._allNodes) {
				return;
			}
			var retval = [];
			$.each(that._allNodes, function(k, val) {
				if(val.state.selected) {
					retval.push(val);
				}
			});
			return retval;
		},

		GetChecked: function() {
			var that = this;
			if(!that._allNodes) {
				return;
			}

			var retval = that.$tree.treeview('getChecked');

			$.each(that._allNodes, function(k, val) {
				if(val.$el.find('.glyphicon-expand').length > 0) {
					retval.push(val);
				}
			});

			return retval;
		},

		SelectNode: function(id, silent) {
			var that = this;
			if(!that._allNodes || !id) {
				return;
			}
			var retval = null;
			$.each(that._allNodes, function(k, val) {
				if(val.id == id.toString()) {
					that.$tree.treeview('selectNode', [val, {
						silent: silent
					}]);
					that._RefreshBreadcrumb(val);
					if(!silent) {
						that._scrollToItem(val.id);
					}
					retval = val;
					return false;
				}
			});
			return retval;
		},

		checkNode: function(id, silent) {
			var that = this;
			if(!that._allNodes || !id) {
				return;
			}

			$.each(that._allNodes, function(k, val) {
				if(val.id == id) {
					that.$tree.treeview('checkNode', [val, {
						silent: silent
					}]);
					return false;
				}
			});
		},

		_RefreshBreadcrumb: function(node) {
			var that = this;
			if(!that.options.breadcrumbID) {
				return;
			}

			that.$breadcrumb.find('ol').empty();
			var item = "";
			if(node != undefined) {
				item = "<li><a href='#' fid='" + node.id + "' nodeId='" + node.nodeId + "'><span>" + node.name + "</span></a></li>";
				GetFullNodePath(node);
			}
			var ico = "<li><a href='#'><span class='fa fa-home'></span></a></li>";
			that.$breadcrumb.find('ol').append(ico + item);

			function GetFullNodePath(thisnode) {
				var pnode = that.$tree.treeview('getParents', thisnode)[0];
				if(pnode && pnode.pid) {
					item = "<li><a href='#' fid='" + pnode.id + "' nodeId='" + pnode.nodeId + "'><span>" + pnode.name + "</span></a></li>" + item;
					GetFullNodePath(pnode);
				}
				return;
			}
		},

		destroy: function() {
			this.$element.empty();
			if(this.options.breadcrumbID) {
				this.$breadcrumb.empty();
			}
		},
	}

	$.fn[pluginName] = function(option) {
		var value;
		var args = Array.prototype.slice.call(arguments, 1);
		this.each(function() {
			var $this = $(this);
			var data = $this.data(pluginName);
			if(typeof option === 'string') {
				if($.inArray(option, methods) < 0) {
					throw new Error("该方法不存在: " + option);
				}
				if(!data) {
					return;
				}
				value = data[option].apply(data, args);

				if(option === 'destroy') {
					$this.removeData(pluginName);
				}
			}
			if(!data) {
				$this.data(pluginName, (data = new vw_searchtree(this, option)));
			}
		});
		return typeof value === 'undefined' ? this : value;
	}
});